﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;

namespace MicroApi.Core.WebSockets
{
    class ClientSession : IClientSession
    {
        private readonly IEnumerable<WebSocketConnection> webSocketConnections;

        private readonly JsonSerializerSettings jsonSerializerSettings;


        public ClientSession(IEnumerable<WebSocketConnection> webSockets, JsonSerializerSettings jsonSerializerSettings = null)
        {
            this.webSocketConnections = webSockets;
            this.jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings()
            {
                DateFormatString = "yyyy-MM-dd HH:mm:ss",
                NullValueHandling = NullValueHandling.Ignore,
                Formatting = Formatting.None,
                FloatFormatHandling = FloatFormatHandling.Symbol,
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
        }


        public bool IsConnecting()
        {
            return webSocketConnections != null && webSocketConnections.Count() > 0;
        }

        public Task SendAsync(string command, object data)
        {
            return SendAsync(new
            {
                command,
                data
            });
        }
        public Task SendAsync(object data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data is string str)
            {
                return Task.WhenAll(webSocketConnections.Select(a => SendAsync(a, str)));
            }
            else if (data is byte[] buffer)
            {
                return Task.WhenAll(webSocketConnections.Select(a => SendAsync(a, buffer)));
            }
            else
            {
                var strJson = JsonConvert.SerializeObject(data, jsonSerializerSettings);
                return Task.WhenAll(webSocketConnections.Select(a => SendAsync(a, strJson)));
            }
        }

        private Task SendAsync(WebSocketConnection session, byte[] bytes)
        {
            return session.SendAsync(bytes);
        }

        private Task SendAsync(WebSocketConnection session, string str)
        {
            return session.SendAsync(str);
        }
    }
}
